"""
pytest配置文件

提供测试环境的全局配置和fixture
"""

import pytest
import asyncio
import sys
import os
from unittest.mock import Mock, AsyncMock
from typing import Dict, Any

# 添加项目根目录到路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from xcquant.core import EventBus, unified_logger
from xcquant.database.database_manager import DatabaseManager


@pytest.fixture(scope="session")
def event_loop():
    """创建事件循环"""
    loop = asyncio.new_event_loop()
    yield loop
    loop.close()


@pytest.fixture
def mock_config():
    """模拟配置"""
    return {
        'strategy': {
            'name': 'test_strategy',
            'symbol': 'BTC/USDT',
            'timeframe': '1h',
            'initial_balance': 10000.0
        },
        'risk': {
            'max_position_size': 0.1,
            'stop_loss': 0.02,
            'take_profit': 0.05,
            'daily_loss_limit': 0.05
        },
        'exchange': {
            'name': 'mock',
            'api_key': 'test_key',
            'api_secret': 'test_secret',
            'sandbox': True
        },
        'database': {
            'type': 'sqlite',
            'path': ':memory:'
        }
    }


@pytest.fixture
def mock_exchange():
    """模拟交易所"""
    exchange = Mock()
    exchange.get_balance = AsyncMock(return_value={'USDT': 10000.0, 'BTC': 0.0})
    exchange.place_order = AsyncMock(return_value={'id': 'test_order_123', 'status': 'open'})
    exchange.cancel_order = AsyncMock(return_value={'id': 'test_order_123', 'status': 'canceled'})
    exchange.get_ticker = AsyncMock(return_value={'bid': 50000.0, 'ask': 50001.0, 'last': 50000.5})
    return exchange


@pytest.fixture
def mock_order_manager():
    """模拟订单管理器"""
    order_manager = Mock()
    order_manager.place_order = AsyncMock(return_value={'id': 'test_order_123', 'status': 'open'})
    order_manager.cancel_order = AsyncMock(return_value=True)
    order_manager.get_active_orders = Mock(return_value=[])
    return order_manager


@pytest.fixture
def mock_account_manager():
    """模拟账户管理器"""
    account_manager = Mock()
    account_manager.get_balance = AsyncMock(return_value={'USDT': 10000.0, 'BTC': 0.0})
    account_manager.update_balance = AsyncMock()
    return account_manager


@pytest.fixture
def mock_data_manager():
    """模拟数据管理器"""
    data_manager = Mock()
    data_manager.get_klines = AsyncMock(return_value=[
        {'timestamp': 1640995200, 'open': 50000, 'high': 51000, 'low': 49000, 'close': 50500, 'volume': 100},
        {'timestamp': 1640998800, 'open': 50500, 'high': 51500, 'low': 49500, 'close': 51000, 'volume': 120}
    ])
    return data_manager


@pytest.fixture
def event_bus():
    """事件总线"""
    return EventBus()


@pytest.fixture
def test_database():
    """测试数据库"""
    config = {
        'database': {
            'type': 'sqlite',
            'path': ':memory:'
        }
    }
    db_manager = DatabaseManager(config)
    db_manager.initialize()
    yield db_manager
    db_manager.close()


@pytest.fixture(autouse=True)
def setup_logging():
    """设置测试日志"""
    # 减少测试时的日志输出
    import logging
    logging.getLogger().setLevel(logging.WARNING)